-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Valueless keys #12
base: master
Are you sure you want to change the base?
Valueless keys #12
Conversation
…he host at runtime) values. environment: - SECRET
Serde_yaml sees the second form as having null values. This matches other YAML libraries I tried. extern crate serde_yaml;
use serde_yaml::Value;
const Y: &str = "
---
environment:
FOO:
BAR:
";
fn main() {
println!("{:#?}", serde_yaml::from_str::<Value>(Y).unwrap());
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for this patch! I think I recall seeing this in the docker-compose.yml
standard, and I would love to have a compliant implementation of this part of the standard.
compose_yml
currently supports the docker-compose.yml
specifications for versions "2" and "2.1" (and we could consider adding support for later "2.x" versions pretty easily, though "3.x" would probably be harder). In particular, we want to make sure that we don't support any non-compliant extensions and that we conform strictly to the standard.
So in order to help us remain compliant, could you please point me to where this behavior is specified in the docker-compose.yml
specs? This will make it easier for code reviewers. (And we need to be careful, given that schema validation is currently broken because of s-panferov/valico#27).
Also, this PR has no test cases. Could you please look at the various assert_roundtrip!
test cases in the code base, and make sure that there are test cases for this feature, showing that it handles (1) all the old behaviors, and (2) the new behavior? Thank you!
To do items:
- A link to the relevant part of the standard for version "2" or "2.1".
- Test cases.
- Other issues mentioned below.
Thank you for this PR!
src/v2/service.rs
Outdated
new_env.append(&mut env_file.to_environment()?); | ||
new_env.extend(env_file.to_environment()? | ||
.into_iter() | ||
.map(|(k, v)| (k, Some(v)))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If environments now have type BTreeMap<String, Option<RawOr<String>>>
, then we should consider updating to_environment
to also return that type, instead of patching it up here. Or is something more complicated going on that we need to think about first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out env_files also accept valueless keys, so we should just handle them there and produce the same BTreeMap
type.
src/v2/helpers.rs
Outdated
} | ||
} | ||
|
||
deserializer.deserialize_map(MapOrKeyOptionalValueListVisitor) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just last night, I discovered in serde-rs/serde#1125 (comment) that there has been a breaking change to the serde
crate, and it is no longer safe to call deserialize_map
as a hint when when override both visit_map
and visit_seq
. This needs to be deserialize_any
(and I need to fix this everywhere else in compose_yml
as well). Sorry for this last minute surprise. :-(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed this, and in the other obvious places too.
@@ -95,7 +95,7 @@ impl<'de> Deserialize<'de> for ConvertToString { | |||
/// | |||
/// ```text | |||
/// struct Example { | |||
/// #[serde(deserialize_with = "deserialize_hash_or_key_value_list")] | |||
/// #[serde(deserialize_with = "deserialize_map_or_key_value_list")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
@@ -72,8 +72,8 @@ pub struct Service { | |||
|
|||
/// Environment variables and values to supply to the container. | |||
#[serde(default, skip_serializing_if = "BTreeMap::is_empty", | |||
deserialize_with = "deserialize_map_or_key_value_list")] | |||
pub environment: BTreeMap<String, RawOr<String>>, | |||
deserialize_with = "deserialize_map_or_key_optional_value_list")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have we looked at all the other callers of deserialize_map_or_key_value_list
and verified that none of them require similar conversions? I can check this if you want, but it will probably have to wait until sometime next week at least.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested all of them with docker_compose
and the only one that doesn't accept valueless keys is driver_opts
. All the others do.
This raises some mildly interesting questions in cage, such as what to do if io.fdy.cage.srcdir
is set but null.
I don't know if there's a spec for The reason I didn't add an environment:
- FOO=bar fails an
|
docker-compose doesn't seem to document this behavior but it does accept these.
Through testing, only the `driver_opts` subkey of `volumes` actually rejects missing values. Everything else that uses `deserialize_map_or_key_value_list` does accept them.
What else needs to happen here? |
@@ -79,6 +82,7 @@ fn parses_docker_compatible_env_files() { | |||
# These are environment variables: | |||
FOO=foo | |||
BAR=2 | |||
BAZ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I can tell from the documentation, this is a non-standard extension to the .env
format:
Compose expects each line in an env file to be in
VAR=VAL
format. Lines beginning with#
(i.e. comments) are ignored, as are blank lines.
So unless we can find some evidence that Docker supports this extension, we should remove this code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the update!
We need to either justify or remove the support for empty keys in .env
.
"value"); | ||
assert_eq!(*build.args.get("other_key").expect("should have other_key"), None); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, good, this is the main test that we need.
I don't see it documented anywhere but it does happen.
|
(docker-compose behaves this way with an explicit |
@khuey OK, if But please keep in mind my comments on faradayio/cage#87 (comment). We don't have any kind of coherent, principled model for how Anyway, this looks about ready to merge. If you don't hear from me by Wednesday, please ping me. |
In
environment
sections you can specify valueless keys likeAnd docker-compose will pick up the relevant values on the machine compose runs on.
The other form,
would require serde_yaml changes, I believe.